<template>
  <div>
    <Cartgory />
    <el-card shadow="always" :body-style="{ padding: '20px' }">
      <template #header>
        <el-button
          type="primary"
          size="default"
          @click="handleToAddAttr"
          :icon="Plus"
          :disabled="!category3Id"
          v-has="'btn.Attr.add'"
          >添加属性</el-button
        >
      </template>
      <!-- card body -->
      <el-table :data="tardemarkAttrListData" border stripe v-if="show">
        <el-table-column type="index" width="88" label="序号" align="center" />
        <el-table-column
          v-for="col in tardemarkAttrListColumns"
          :prop="col.id"
          :key="col.id"
          :label="col.label"
          :width="col.width"
        >
          <template #default="{ row }" v-if="col.id === 'attrValueList'">
            <el-tag
              class="ml-2"
              type="success"
              v-for="item in row.attrValueList"
              :key="item.id"
              >{{ item.valueName }}</el-tag
            >
          </template>
        </el-table-column>
        <el-table-column label="操作" width="150" align="center">
          <template #default="{ row }">
            <div>
              <el-button
                type="warning"
                size="default"
                @click="handleToUpdateAttr(row)"
                :icon="Edit"
                v-has="'btn.Attr.update'"
              ></el-button>
              <el-popconfirm
                title="你确定要删除这个属性吗?"
                @confirm="handleDeleteAttr(row)"
              >
                <template #reference>
                  <el-button
                    type="danger"
                    size="default"
                    :icon="Delete"
                    v-has="'btn.Attr.remove'"
                  ></el-button>
                </template>
              </el-popconfirm>
            </div>
          </template>
        </el-table-column>
      </el-table>
      <div v-else>
        <el-form
          :model="tardemarkAttrFormData"
          ref="attrFromRef"
          :rules="attrFromRules"
          label-width="80px"
          :inline="true"
          size="default"
        >
          <el-form-item label="属性名" prop="attrName">
            <el-input v-model="tardemarkAttrFormData.attrName"></el-input>
          </el-form-item>
          <el-form-item>
            <el-button type="primary" @click="handleCreateAttr"
              >立即创建</el-button
            >
            <el-button @click="handleCancle">取消</el-button>
          </el-form-item>
        </el-form>
        <el-table :data="tardemarkAttrFormData.attrValueList" border stripe>
          <el-table-column type="index" width="80" label="序号" />
          <el-table-column
            v-for="col in attrValueTableColumns"
            :prop="col.id"
            :key="col.id"
            :label="col.label"
            :width="col.width"
          >
            <template #default="{ row, $index }">
              <div>
                <el-input
                  v-model="row.valueName"
                  placeholder="请输入新增的属性值名称"
                  size="default"
                  clearable
                  v-if="row.isEdit"
                  ref="inputEditRef"
                  @blur="handleSwitchEdit(row, $index)"
                  @focus="handleInputAVFocus(row)"
                ></el-input>
                <p
                  v-else
                  @click="handleSwitchEdit(row, $index)"
                  class="attrValueText"
                >
                  {{ row.valueName }}
                </p>
              </div>
            </template>
          </el-table-column>
          <el-table-column label="操作">
            <template v-slot="{ $index }">
              <!-- 气泡确认框 -->
              <el-popconfirm
                title="你确定要删除这个属性吗?"
                @confirm="handleDeleteAttrValue($index)"
              >
                <template #reference>
                  <el-button
                    type="danger"
                    size="small"
                    icon="ele-Delete"
                  ></el-button>
                </template>
              </el-popconfirm>
            </template>
          </el-table-column>
        </el-table>
        <div style="margin-top: 30px">
          <el-button type="primary" @click="handleSaveAttr">保存</el-button>
          <el-button type="default" @click="handleCancleSaveAttr"
            >取消</el-button
          >
        </div>
      </div>
    </el-card>
  </div>
</template>

<script lang="ts">
import { defineComponent } from "vue";

export default defineComponent({
  name: "Attr",
});
</script>

<script setup lang="ts">
import Cartgory from "@/components/Cartgory/index.vue";

import { nextTick, ref, watch } from "vue";

import { ElMessage, type FormInstance, type FormRules } from "element-plus";
import { Plus, Edit, Delete } from "@element-plus/icons-vue";

import { cloneDeep } from "lodash";

import type {
  RequestTardemarkAttrListReturnAttrValueListItemType,
  RequestTardemarkAttrListReturnItemType,
  RequestTardemarkAttrListReturnType,
} from "@/api/product/interface";
import {
  requestAddOrUpdateTardemarkAttr,
  requestTardemarkAttrList,
  requestDeleteTardemarkAttr,
} from "@/api/product";

import { useCartgoryStore } from "@/stores/cartgory";
import { storeToRefs } from "pinia";

/* table 数据 */
const tardemarkAttrListData = ref<RequestTardemarkAttrListReturnType>([]);
const tardemarkAttrListColumns = [
  {
    id: "attrName",
    label: "属性名称",
    width: "100",
  },
  {
    id: "attrValueList",
    label: "属性值名称列表",
    width: "",
  },
];

/* pinia */
const cartgoryStore = useCartgoryStore();
const { category1Id, category2Id, category3Id } = storeToRefs(cartgoryStore);

const getTardemarkAttrListData = async () => {
  try {
    tardemarkAttrListData.value = await requestTardemarkAttrList({
      category1Id: category1Id.value as number,
      category2Id: category2Id.value as number,
      category3Id: category3Id.value as number,
    });
  } catch (error) {
    ElMessage.error("品牌属性数据获取失败！！！");
  }
};
// 当三级分类发生改变书时，请求品牌属性列表数据(直接监听 attrStore 中 category3Id 的变化)
watch(
  category3Id,
  (newVal) => {
    // 判断没有 category3Id 就不请求数据
    if (!newVal) return (tardemarkAttrListData.value = []);
    getTardemarkAttrListData();
  },
  { immediate: true }
);

/* 新增 */
const show = ref(true);
// 表单数据
const tardemarkAttrFormData = ref<RequestTardemarkAttrListReturnItemType>({
  attrName: "",
  attrValueList: [],
  categoryId: category3Id.value as number,
  categoryLevel: 3,
});
const attrFromRef = ref<FormInstance>();
const attrFromRules = ref<FormRules>({
  attrName: [{ required: true, message: "属性名必填！", trigger: "blur" }],
});
// 属性值名称列表的表头
const attrValueTableColumns = ref([
  {
    id: "valueName",
    label: "属性值名称",
    width: "",
  },
]);
// 切换添加属性组件事件
const handleToAddAttr = () => {
  // 切换新增组件
  show.value = false;
  // 初始化对应的属性数据(防止数据残留)
  tardemarkAttrFormData.value = {
    // 新增的数据回填没有 id
    attrName: "",
    attrValueList: [],
    categoryId: category3Id.value as number,
    categoryLevel: 3,
  };
};
// 取消添加&修改事件回调
const handleCancle = () => {
  // 切换属性列表组件
  show.value = true;
};
// 创建属性事件
const inputEditRef = ref();
const handleCreateAttr = async () => {
  // 验证表单规则
  try {
    await attrFromRef.value?.validate();
  } catch (error) {
    return ElMessage("表单校验失败！");
  }
  // 生成新的属性名数据
  const newAttrValue = ref({
    attrId: tardemarkAttrFormData.value.id,
    valueName: "",
    isEdit: true,
  });
  // 向 tardemarkAttrFormData.attrValueList 中添加属性值名称
  tardemarkAttrFormData.value.attrValueList.unshift(newAttrValue.value);
  // 生成的 input 输入框，自动获取焦点(vue 是异步渲染视图的，此时无法获取到由该数据生成的 DOM，可以使用 nextTick)
  nextTick(() => {
    inputEditRef.value[0].focus();
  });
};
// 编辑模式切换
const handleSwitchEdit = (
  row: RequestTardemarkAttrListReturnAttrValueListItemType,
  $index: number
) => {
  row.isEdit = !row.isEdit;
  if (row.isEdit) {
    // 是编辑模式直接退出
    return nextTick(() => {
      inputEditRef.value[0].focus();
    });
  }
  // 判断输入是否为空
  if (!row.valueName.trim()) {
    // 根据是否有原值来判断是否为直接清空原值
    if (oldAttrValue) {
      // 有原始值，将数据恢复至原始值
      row.valueName = oldAttrValue;
    } else {
      // 没有初始值，表明这是用户新增的数据，为空直接删除
      tardemarkAttrFormData.value.attrValueList.splice($index, 1);
    }
  }
  //判断用户输入的是否有重复选项,如果有,则恢复
  let isRepeat = tardemarkAttrFormData.value.attrValueList.some((item) => {
    //如果自己比较自己的时候,我们跳过(不挑过的话,永远isRepeat为true)
    if (item === row) {
      return;
    }
    return item.valueName === row.valueName;
  });
  //判断在数据列表中除了row自身以外,还有没有谁的valueName值和row的相等,如果有,则恢复旧值
  if (isRepeat) {
    if (oldAttrValue) {
      row.valueName = oldAttrValue;
    } else {
      tardemarkAttrFormData.value.attrValueList.splice($index, 1);
    }
  }
};

/* 修改 */
const handleToUpdateAttr = (row: RequestTardemarkAttrListReturnItemType) => {
  // 切换修改组件
  show.value = false;
  // 数据回填(进行深拷贝)(不用填充 isEdit 没有默认为 undefined)
  tardemarkAttrFormData.value = cloneDeep(row); // 修改的数据回填有 id
};
// 解决将源数据直接清空后填充原来的值
let oldAttrValue = "";
const handleInputAVFocus = (
  row: RequestTardemarkAttrListReturnAttrValueListItemType
) => {
  // 保存原来的值
  oldAttrValue = row.valueName;
};
// 删除单个属性
const handleDeleteAttrValue = ($index: number) => {
  tardemarkAttrFormData.value.attrValueList.splice($index, 1);
};
// 保存
const handleSaveAttr = async () => {
  // 数据校验

  if (tardemarkAttrFormData.value.attrValueList.length <= 0) {
    return ElMessage.error("属性列表的数据不能为空！");
  }
  tardemarkAttrFormData.value.attrValueList.forEach((item) => {
    delete item.isEdit;
  });
  // 提交数据请求
  try {
    await requestAddOrUpdateTardemarkAttr(tardemarkAttrFormData.value);
    ElMessage.success(tardemarkAttrFormData.value.id ? "修改成功" : "新增成功");
    // 切换为数据展示页
    show.value = true;
    // 重新请求数据
    getTardemarkAttrListData();
  } catch (error) {
    ElMessage.error(tardemarkAttrFormData.value.id ? "修改失败" : "新增失败");
  }
};
// 取消
const handleCancleSaveAttr = () => {
  show.value = true;
};

/* 删除 */
const handleDeleteAttr = async (
  row: RequestTardemarkAttrListReturnItemType
) => {
  try {
    await requestDeleteTardemarkAttr(row.id as number);
    ElMessage.success("删除成功");
    getTardemarkAttrListData();
  } catch (error) {
    ElMessage.error("删除失败");
  }
};
</script>

<style scoped>
.attrValueText {
  width: 100%;
  height: 32px;
  line-height: 32px;
}
</style>
